<!--  -->
<template>
  <div class="el-upload-container" :class="containerClass" v-loading="loading" :element-loading-text="loadingText">
    <!-- 上传控件 -->
    <el-upload
      v-model="value"
      class="el-upload-controls"
      :class="uploadClass" 
      drag
      :show-file-list="false"
      :http-request="uploadFile"
      :accept="accept"
      :multiple="multiple"
      v-if="showUploadControls"
    >
      <el-icon class="el-icon--upload">
        <upload-filled />
      </el-icon>
      <div class="el-upload__text">拖拽到此上传或者<em>点击上传</em></div>
    </el-upload>
    <SingleFile
      :data="props.modelValue"
      v-if="!props.multiple && !showUploadControls && typeof props.modelValue === 'string'"
      @delete-file="onDeleteFile"
    />
    <FileList
      :data="props.modelValue"
      v-if="props.multiple && Array.isArray(props.modelValue)"
      @delete-file="onDeleteFile"
      :fileListStyle="fileListStyle"
      :fileListItemStyle="fileListItemStyle"
    />
  </div>
</template>
<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue';
import SingleFile from './components/SingleFile.vue'
import FileList from './components/FileList.vue'
import { UploadRequestHandler, UploadRequestOptions, vLoading } from 'element-plus';
import { uploadFileApi } from '@/global/api/common';
import { StyleValue } from 'vue';

const value = ref('')

// 组件参数
const props = defineProps<{
  modelValue: string | string[] | undefined,
  accept?: string,
  verifyLegal?: (file: File) => Promise<boolean>,
  multiple?: boolean,
  fileListStyle?: StyleValue,
  fileListItemStyle?: StyleValue,
  uploadClass?: string,
  containerClass?: string
}>()
const emits = defineEmits([`update:modelValue`, `change`])
// 是否显示上传组件
const showUploadControls = computed(() => {
  let flag = true
  if (!props.multiple) {
    if (props.modelValue) {
      flag = false
    }
  }
  return flag
})
// 加载信息
const loading = ref(false)
const loadingText = ref('正在上传，请稍等...')

/**
 * 上传文件
 */
const uploadFile: UploadRequestHandler = (options: UploadRequestOptions) => new Promise(async (resolve, reject) => {
  let file = options.file
  let flag = true
  // 如果需要外部验证比如文件类型，那么需要先通过外部验证
  if (props.verifyLegal) {
    flag = await props.verifyLegal(file) ?? true
    if (typeof flag !== 'boolean') {
      flag = true
    }
  }
  if (flag) {
    let sendData = new FormData()
    sendData.append('file', file)
    loading.value = true

    uploadFileApi(sendData).then((res: KeyValue) => {
      // 如果是多选 那么假如数组 否则是替换原有值
      if (props.multiple) {
        let arr = (props.modelValue && Array.isArray(props.modelValue)) ? props.modelValue : []
        arr.push(res.data.url)
        emits('update:modelValue', arr)
        emits('change', `upload`, arr)
      } else {
        emits('update:modelValue', res.data.url)
        emits('change', `upload`, res.data.url)
      }
    }).finally(() => {
      loading.value = false
    })
  }
});
/**
 * 删除文件
 */
const onDeleteFile = (key?: number) => {
  if (props.multiple) {
    let arr = (props.modelValue && Array.isArray(props.modelValue) && props.modelValue.length > 0) ? props.modelValue : []
    if (key || key === 0) {
      arr.splice(key, 1)
    }
    console.log(arr)
    emits('update:modelValue', arr)
  } else {
    emits('update:modelValue', '')
  }
}

</script>
<style scoped lang="scss">
</style>
<style lang="scss">
  .el-upload-container {
    width: 100%;
    height: 100%;
    position: relative;
    .el-upload-controls {
      width: 100%;
      height: 100%;
      .is-drag {
        width: 100%;
        height: 100%;
        .el-upload-dragger {
          width: 100%;
          height: 100%;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
        }
      }
    }
  }
</style>
